import * as crypto from "node:crypto";

export class RSAUtil {
    static #KEY_SIZE = 2048;

    /**
     * 生成RSA密钥对
     */
    static generateKeyPair() {
        return crypto.generateKeyPairSync('rsa', {
            modulusLength: this.#KEY_SIZE,
            publicKeyEncoding: {
                type: 'spki',
                format: 'pem'
            },
            privateKeyEncoding: {
                type: 'pkcs8',
                format: 'pem'
            }
        });
    }

    /**
     * 生成Base64编码的公私钥字符串
     * @returns {string[]} 数组中index 0为公钥，1为私钥
     */
    static generateKeyStrings() {
        const { publicKey, privateKey } = this.generateKeyPair();

        // 转换为纯Base64格式
        const publicKeyBase64 = publicKey
            .replace('-----BEGIN PUBLIC KEY-----\n', '')
            .replace('\n-----END PUBLIC KEY-----', '')
            .replace(/\n/g, '');

        const privateKeyBase64 = privateKey
            .replace('-----BEGIN PRIVATE KEY-----\n', '')
            .replace('\n-----END PRIVATE KEY-----', '')
            .replace(/\n/g, '');

        return [publicKeyBase64, privateKeyBase64];
    }

    /**
     * 处理密钥字符串，确保PEM格式
     */
    static #formatPublicKey(key) {
        key = key.replace(/-----(BEGIN|END) PUBLIC KEY-----/g, '').replace(/\s+/g, '');
        return '-----BEGIN PUBLIC KEY-----\n' +
            key.match(/.{1,64}/g).join('\n') +
            '\n-----END PUBLIC KEY-----';
    }

    static #formatPrivateKey(key) {
        key = key.replace(/-----(BEGIN|END) PRIVATE KEY-----/g, '').replace(/\s+/g, '');
        return '-----BEGIN PRIVATE KEY-----\n' +
            key.match(/.{1,64}/g).join('\n') +
            '\n-----END PRIVATE KEY-----';
    }

    /**
     * 使用公钥加密
     * @param {string} publicKeyStr - Base64编码的公钥
     * @param {string} plainText - 明文
     * @returns {string} Base64编码的密文
     */
    static encrypt(publicKeyStr, plainText) {
        const formattedKey = this.#formatPublicKey(publicKeyStr);

        const encrypted = crypto.publicEncrypt(
            {
                key: formattedKey,
                padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
                oaepHash: 'sha1'  // 改为sha1
            },
            Buffer.from(plainText)
        );

        return encrypted.toString('base64');
    }

    /**
     * 使用私钥解密
     * @param {string} privateKeyStr - Base64编码的私钥
     * @param {string} encryptedText - Base64编码的密文
     * @returns {string} 明文
     */
    static decrypt(privateKeyStr, encryptedText) {
        const formattedKey = this.#formatPrivateKey(privateKeyStr);

        const decrypted = crypto.privateDecrypt(
            {
                key: formattedKey,
                padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
                oaepHash: 'sha1'  // 改为sha1
            },
            Buffer.from(encryptedText, 'base64')
        );

        return decrypted.toString();
    }
}